package java3.io;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class CalculoLoser {

    private static final int pawn = 1;
    private static final int knight = 2;
    private static final int bishop = 3;
    private static final int rook = 4;
    private static final int queen = 5;
    private static final int king = 6;
    private static final int white = 0;
    private static final int black = 1;
    private static final int vacio = 0;
    private static final int sincolor = 2;
    private UtilLoser util;
    public static int request;

    public CalculoLoser() {
        util = new UtilLoser();
    }

    public CalculoLoser(UtilLoser util) {
        this.util = util;
    }

    public Jugadas devolverJugadas(int[][] tablero,
            int jugador, int ini, int fin, boolean enroquecorto, boolean enroquelargo, boolean eslocal) {
        request++;
        Jugadas jugadas = new Jugadas();
        List<int[]> movimientos = new ArrayList<>();
        List<int[]> movimientosObligados = new ArrayList<>();
        Map<Integer, Movimientos> amenazasescondidas;
        boolean esObligatorio = false;
        int[] amenazasrival;
        int pos_king;
        int pos_jaque;
        Movimientos esc;
        int rival;

        rival = jugador == white ? black : white;

        pos_king = util.devuelvePosicionRey(tablero, jugador);
        amenazasrival = this.devolverCasillasAmenazadas(tablero, rival);
        amenazasescondidas = this.devolverCasillasAmenazadasEscondidas(tablero, rival, jugador, ini, fin, pos_king);
        pos_jaque = util.esJaque(amenazasrival);

        if (pos_jaque != -1) {//si hay jaque
            this.buscarJugadasenJaque(jugadas, tablero, amenazasrival, jugador, ini, fin,
                    amenazasescondidas, pos_king, pos_jaque, rival);
            if (eslocal) {
                if (jugadas.isEsObligatorio()) {
                    movimientosObligados = jugadas.getJugadas();

                    if (movimientosObligados.size() > 1) {
                        jugadas.setJugadas(util.ordenarCapturas(movimientosObligados, amenazasrival));
                    }
                } else if (jugadas.isHayJaque()) {
                    movimientos = jugadas.getJugadas();

                    if (movimientos.size() > 1) {
                        jugadas.setJugadas(util.ordenarJaque(movimientos, tablero, jugador));
                    }
                }
            }
        } else {
            int ficha;
            int color;

            for (int i = 0; i < 64; i++) {
                color = tablero[1][i];

                if (color == jugador) {
                    esc = amenazasescondidas.get(i);

                    if (esc != null && esc.isSinMovimientos()) {
                        continue;
                    }

                    ficha = tablero[0][i];
                    switch (ficha) {
                        case pawn:
                            switch (color) {
                                case white:
                                    if (tablero[0][i + 8] == vacio && (esc == null || esc.isVerticalSuperior()) && !esObligatorio) {

                                        if (i + 8 > 55 && i + 8 < 64) {
                                            movimientos.add(armarJugadaConProm(i, i + 8, pawn, queen));
                                            movimientos.add(armarJugadaConProm(i, i + 8, pawn, rook));
                                            movimientos.add(armarJugadaConProm(i, i + 8, pawn, bishop));
                                            movimientos.add(armarJugadaConProm(i, i + 8, pawn, knight));
                                        } else {
                                            movimientos.add(armarJugada(i, i + 8, pawn));
                                            if ((i >= 8 && i <= 15) && tablero[0][i + 16] == vacio) {
                                                movimientos.add(armarJugada(i, i + 16, pawn));
                                            }
                                        }
                                    }
                                    if (i % 8 != 0 && (esc == null || esc.isDiagonalSuperiorIzquierda())) {
                                        if (tablero[0][i + 7] != vacio) {
                                            if (tablero[1][i + 7] == black) {
                                                if (i + 7 > 55 && i + 7 < 64) {
                                                    movimientosObligados.add(armarJugadaConProm(i, i + 7, pawn, queen));
                                                    movimientosObligados.add(armarJugadaConProm(i, i + 7, pawn, rook));
                                                    movimientosObligados.add(armarJugadaConProm(i, i + 7, pawn, bishop));
                                                    movimientosObligados.add(armarJugadaConProm(i, i + 7, pawn, knight));
                                                } else {
                                                    movimientosObligados.add(armarJugada(i, i + 7, pawn));
                                                }
                                                esObligatorio = true;
                                            }
                                        } else {
                                            if (ini != -1 && fin != -1 && tablero[0][fin] == pawn) {
                                                if (ini >= 48 && ini <= 55 && fin == ini - 16 && fin == i - 1) {
                                                    esObligatorio = true;
                                                    movimientosObligados.add(armarJugada(i, i + 7, pawn));
                                                }
                                            }
                                        }
                                    }
                                    if ((i + 1) % 8 != 0 && (esc == null || esc.isDiagonalSuperiorDerecha())) {
                                        if (tablero[0][i + 9] != vacio) {
                                            if (tablero[1][i + 9] == black) {
                                                if (i + 9 > 55 && i + 9 < 64) {
                                                    movimientosObligados.add(armarJugadaConProm(i, i + 9, pawn, queen));
                                                    movimientosObligados.add(armarJugadaConProm(i, i + 9, pawn, rook));
                                                    movimientosObligados.add(armarJugadaConProm(i, i + 9, pawn, bishop));
                                                    movimientosObligados.add(armarJugadaConProm(i, i + 9, pawn, knight));
                                                } else {
                                                    movimientosObligados.add(armarJugada(i, i + 9, pawn));
                                                }
                                                esObligatorio = true;
                                            }
                                        } else {
                                            if (ini != -1 && fin != -1 && tablero[0][fin] == pawn) {
                                                if (ini >= 48 && ini <= 55 && fin == ini - 16 && fin == i + 1) {
                                                    movimientosObligados.add(armarJugada(i, i + 9, pawn));
                                                    esObligatorio = true;
                                                }
                                            }
                                        }
                                    }
                                    break;
                                case black:
                                    if (tablero[0][i - 8] == vacio && (esc == null || esc.isVerticalInferior()) && !esObligatorio) {
                                        if (i - 8 >= 0 && i - 8 < 8) {
                                            movimientos.add(armarJugadaConProm(i, i - 8, pawn, queen));
                                            movimientos.add(armarJugadaConProm(i, i - 8, pawn, rook));
                                            movimientos.add(armarJugadaConProm(i, i - 8, pawn, bishop));
                                            movimientos.add(armarJugadaConProm(i, i - 8, pawn, knight));
                                        } else {
                                            movimientos.add(armarJugada(i, i - 8, pawn));
                                            if ((i >= 48 && i <= 55) && tablero[0][i - 16] == vacio) {
                                                movimientos.add(armarJugada(i, i - 16, pawn));
                                            }
                                        }
                                    }
                                    if ((i + 1) % 8 != 0 && (esc == null || esc.isDiagonalInferiorDerecha())) {
                                        if (tablero[0][i - 7] != vacio) {
                                            if (tablero[1][i - 7] == white) {
                                                if (i - 7 > 0 && i - 7 < 8) {
                                                    movimientosObligados.add(armarJugadaConProm(i, i - 7, pawn, queen));
                                                    movimientosObligados.add(armarJugadaConProm(i, i - 7, pawn, rook));
                                                    movimientosObligados.add(armarJugadaConProm(i, i - 7, pawn, bishop));
                                                    movimientosObligados.add(armarJugadaConProm(i, i - 7, pawn, knight));

                                                } else {
                                                    movimientosObligados.add(armarJugada(i, i - 7, pawn));
                                                }
                                                esObligatorio = true;
                                            }
                                        } else {
                                            if (ini != -1 && fin != -1 && tablero[0][fin] == pawn) {
                                                if (ini >= 8 && ini <= 15 && fin == ini + 16 && fin == i + 1) {
                                                    movimientosObligados.add(armarJugada(i, i - 7, pawn));
                                                    esObligatorio = true;
                                                }
                                            }
                                        }
                                    }
                                    if (i % 8 != 0 && (esc == null || esc.isDiagonalInferiorIzquierda())) {
                                        if (tablero[0][i - 9] != vacio) {
                                            if (tablero[1][i - 9] == white) {
                                                if (i - 9 >= 0 && i - 9 < 8) {
                                                    movimientosObligados.add(armarJugadaConProm(i, i - 9, pawn, queen));
                                                    movimientosObligados.add(armarJugadaConProm(i, i - 9, pawn, rook));
                                                    movimientosObligados.add(armarJugadaConProm(i, i - 9, pawn, bishop));
                                                    movimientosObligados.add(armarJugadaConProm(i, i - 9, pawn, knight));
                                                } else {
                                                    movimientosObligados.add(armarJugada(i, i - 9, pawn));
                                                }
                                                esObligatorio = true;
                                            }
                                        } else {
                                            if (ini != -1 && fin != -1 && tablero[0][fin] == pawn) {
                                                if (ini >= 8 && ini <= 15 && fin == ini + 16 && fin == i - 1) {
                                                    movimientosObligados.add(armarJugada(i, i - 9, pawn));
                                                    esObligatorio = true;
                                                }
                                            }
                                        }
                                    }
                                    break;
                            }
                            break;
                        case knight:
                            //+6 -6
                            if (i < 56 && i % 8 > 1) {
                                if (tablero[1][i + 6] == sincolor) {
                                    if (!esObligatorio) {
                                        movimientos.add(armarJugada(i, i + 6, knight));
                                    }
                                } else if (tablero[1][i + 6] != jugador) {
                                    movimientosObligados.add(armarJugada(i, i + 6, knight));
                                    esObligatorio = true;
                                }
                            }
                            if (i > 7 && i % 8 < 6) {
                                if (tablero[1][i - 6] == sincolor) {
                                    if (!esObligatorio) {
                                        movimientos.add(armarJugada(i, i - 6, knight));
                                    }
                                } else if (tablero[1][i - 6] != jugador) {
                                    movimientosObligados.add(armarJugada(i, i - 6, knight));
                                    esObligatorio = true;
                                }
                            }
                            //+10 -10
                            if (i < 56 && i % 8 < 6) {
                                if (tablero[1][i + 10] == sincolor) {
                                    if (!esObligatorio) {
                                        movimientos.add(armarJugada(i, i + 10, knight));
                                    }
                                } else if (tablero[1][i + 10] != jugador) {
                                    movimientosObligados.add(armarJugada(i, i + 10, knight));
                                    esObligatorio = true;
                                }
                            }
                            if (i > 7 && i % 8 > 1) {
                                if (tablero[1][i - 10] == sincolor) {
                                    if (!esObligatorio) {
                                        movimientos.add(armarJugada(i, i - 10, knight));
                                    }
                                } else if (tablero[1][i - 10] != jugador) {
                                    movimientosObligados.add(armarJugada(i, i + -10, knight));
                                    esObligatorio = true;
                                }
                            }
                            //+15 -15
                            if (i < 48 && i % 8 > 0) {
                                if (tablero[1][i + 15] == sincolor) {
                                    if (!esObligatorio) {
                                        movimientos.add(armarJugada(i, i + 15, knight));
                                    }
                                } else if (tablero[1][i + 15] != jugador) {
                                    movimientosObligados.add(armarJugada(i, i + 15, knight));
                                    esObligatorio = true;
                                }
                            }
                            if (i > 15 && i % 8 < 7) {
                                if (tablero[1][i - 15] == sincolor) {
                                    if (!esObligatorio) {
                                        movimientos.add(armarJugada(i, i - 15, knight));
                                    }
                                } else if (tablero[1][i - 15] != jugador) {
                                    movimientosObligados.add(armarJugada(i, i - 15, knight));
                                    esObligatorio = true;
                                }
                            }
                            //+17 -17
                            if (i < 48 && i % 8 < 7) {
                                if (tablero[1][i + 17] == sincolor) {
                                    if (!esObligatorio) {
                                        movimientos.add(armarJugada(i, i + 17, knight));
                                    }
                                } else if (tablero[1][i + 17] != jugador) {
                                    movimientosObligados.add(armarJugada(i, i + 17, knight));
                                    esObligatorio = true;
                                }
                            }
                            if (i > 15 && i % 8 > 0) {
                                if (tablero[1][i - 17] == sincolor) {
                                    if (!esObligatorio) {
                                        movimientos.add(armarJugada(i, i - 17, knight));
                                    }
                                } else if (tablero[1][i - 17] != jugador) {
                                    movimientosObligados.add(armarJugada(i, i - 17, knight));
                                    esObligatorio = true;
                                }
                            }
                            break;
                        case bishop:
                            esObligatorio = this.buscarMovimientosDiagonal(tablero, i, jugador, true, bishop, null, esc,
                                    movimientos, movimientosObligados, esObligatorio);
                            break;
                        case rook:
                            esObligatorio = this.buscarMovimientosHorizontalVertical(tablero, i, jugador, true, rook, null, esc,
                                    movimientos, movimientosObligados, esObligatorio);
                            break;
                        case queen:
                            esObligatorio = this.buscarMovimientosDiagonal(tablero, i, jugador, true, queen, null, esc,
                                    movimientos, movimientosObligados, esObligatorio);
                            esObligatorio = this.buscarMovimientosHorizontalVertical(tablero, i, jugador, true, queen, null, esc,
                                    movimientos, movimientosObligados, esObligatorio);
                            break;
                        case king:
                            esObligatorio = this.buscarMovimientosDiagonal(tablero, i, jugador, false, king, amenazasrival, esc,
                                    movimientos, movimientosObligados, esObligatorio);
                            esObligatorio = this.buscarMovimientosHorizontalVertical(tablero, i, jugador, false, king, amenazasrival, esc,
                                    movimientos, movimientosObligados, esObligatorio);

                            if (enroquecorto && !esObligatorio) {
                                switch (color) {
                                    case white:
                                        if (i == 4 && tablero[0][5] == vacio && tablero[0][6] == vacio && tablero[0][7] == rook) {
                                            if (!util.siArrayContiene(amenazasrival, 4) && !util.siArrayContiene(amenazasrival, 5) && !util.siArrayContiene(amenazasrival, 6)) {
                                                movimientos.add(armarJugada(4, 6, king));
                                            }
                                        }
                                        break;
                                    case black:
                                        if (i == 60 && tablero[0][61] == vacio && tablero[0][62] == vacio && tablero[0][63] == rook) {
                                            if (!util.siArrayContiene(amenazasrival, 60) && !util.siArrayContiene(amenazasrival, 61) && !util.siArrayContiene(amenazasrival, 62)) {
                                                movimientos.add(armarJugada(60, 62, king));
                                            }
                                        }
                                        break;
                                }
                            }
                            if (enroquelargo && !esObligatorio) {
                                switch (color) {
                                    case white:
                                        if (i == 4 && tablero[0][3] == vacio && tablero[0][2] == vacio && tablero[0][1] == vacio && tablero[0][0] == rook) {
                                            if (!util.siArrayContiene(amenazasrival, 4) && !util.siArrayContiene(amenazasrival, 3) && !util.siArrayContiene(amenazasrival, 2)) {
                                                movimientos.add(armarJugada(4, 2, king));
                                            }
                                        }
                                        break;
                                    case black:
                                        if (i == 60 && tablero[0][59] == vacio && tablero[0][58] == vacio && tablero[0][57] == vacio && tablero[0][56] == rook) {
                                            if (!util.siArrayContiene(amenazasrival, 60) && !util.siArrayContiene(amenazasrival, 59) && !util.siArrayContiene(amenazasrival, 58)) {
                                                movimientos.add(armarJugada(60, 58, king));
                                            }
                                        }
                                        break;
                                }
                            }
                            break;
                    }
                }
            }
            //ordenar jugadas
            if (esObligatorio) {
                jugadas.setEsObligatorio(true);
                if (movimientosObligados.size() > 1) {
                    jugadas.setJugadas(eslocal ? util.ordenarCapturas(movimientosObligados, amenazasrival) : movimientosObligados);
                } else {
                    jugadas.setJugadas(movimientosObligados);
                }
            } else {
                jugadas.setEsObligatorio(false);
                if (movimientos.size() > 1) {
                    int [] amenazas = this.devolverCasillasAmenazadas(tablero, jugador);
                    int p_king = util.devuelvePosicionRey(tablero, rival);
                    jugadas.setJugadas(eslocal ? util.ordenarJugadasLocal(movimientos, tablero, amenazas, amenazasrival, jugador, p_king) : movimientos);
                } else {
                    jugadas.setJugadas(movimientos);
                }
            }
        }

        return jugadas;
    }

    private boolean buscarMovimientosDiagonal(int[][] tablero, int posicion,
            int jugador, boolean esRecursivo, int pieza, int[] amenazas, Movimientos esc,
            List<int[]> movimientos, List<int[]> movimientosObligados, boolean esObligatorio) {

        int factor = 1;
        int val;
        boolean a7 = true,
                b7 = true,
                a9 = true,
                b9 = true;
        do {
            if (a7) {
                val = posicion - (7 * factor);
                if (val % 8 > 0 && (esc == null || esc.isDiagonalInferiorDerecha())) {
                    if (tablero[1][val] == sincolor) {
                        if (!esObligatorio) {
                            if (!esRecursivo) {
                                if (!util.siArrayContiene(amenazas, val)) {
                                    movimientos.add(armarJugada(posicion, val, pieza));
                                }
                            } else {
                                movimientos.add(armarJugada(posicion, val, pieza));
                            }
                        }
                    } else {
                        if (tablero[1][val] != jugador) {
                            if (!esRecursivo) {
                                if (!util.siArrayContiene(amenazas, val)) {
                                    movimientosObligados.add(armarJugada(posicion, val, pieza));
                                    esObligatorio = true;
                                }
                            } else {
                                movimientosObligados.add(armarJugada(posicion, val, pieza));
                                esObligatorio = true;
                            }
                        }
                        a7 = false;
                    }
                } else {
                    a7 = false;
                }
            }
            if (b7) {
                val = posicion + (7 * factor);
                if (val < 64 && val % 8 < 7 && (esc == null || esc.isDiagonalSuperiorIzquierda())) {
                    if (tablero[1][val] == sincolor) {
                        if (!esObligatorio) {
                            if (!esRecursivo) {
                                if (!util.siArrayContiene(amenazas, val)) {
                                    movimientos.add(armarJugada(posicion, val, pieza));
                                }
                            } else {
                                movimientos.add(armarJugada(posicion, val, pieza));
                            }
                        }
                    } else {
                        if (tablero[1][val] != jugador) {
                            if (!esRecursivo) {
                                if (!util.siArrayContiene(amenazas, val)) {
                                    movimientosObligados.add(armarJugada(posicion, val, pieza));
                                    esObligatorio = true;
                                }
                            } else {
                                movimientosObligados.add(armarJugada(posicion, val, pieza));
                                esObligatorio = true;
                            }
                        }
                        b7 = false;
                    }
                } else {
                    b7 = false;
                }
            }
            if (a9) {
                val = posicion - (9 * factor);
                if (val >= 0 && val % 8 < 7 && (esc == null || esc.isDiagonalInferiorIzquierda())) {
                    if (tablero[1][val] == sincolor) {
                        if (!esObligatorio) {
                            if (!esRecursivo) {
                                if (!util.siArrayContiene(amenazas, val)) {
                                    movimientos.add(armarJugada(posicion, val, pieza));
                                }
                            } else {
                                movimientos.add(armarJugada(posicion, val, pieza));
                            }
                        }
                    } else {
                        if (tablero[1][val] != jugador) {
                            if (!esRecursivo) {
                                if (!util.siArrayContiene(amenazas, val)) {
                                    movimientosObligados.add(armarJugada(posicion, val, pieza));
                                    esObligatorio = true;
                                }
                            } else {
                                movimientosObligados.add(armarJugada(posicion, val, pieza));
                                esObligatorio = true;
                            }
                        }
                        a9 = false;
                    }
                } else {
                    a9 = false;
                }
            }
            if (b9) {
                val = posicion + (9 * factor);
                if (val < 64 && val % 8 > 0 && (esc == null || esc.isDiagonalSuperiorDerecha())) {
                    if (tablero[1][val] == sincolor) {
                        if (!esObligatorio) {
                            if (!esRecursivo) {
                                if (!util.siArrayContiene(amenazas, val)) {
                                    movimientos.add(armarJugada(posicion, val, pieza));
                                }
                            } else {
                                movimientos.add(armarJugada(posicion, val, pieza));
                            }
                        }
                    } else {
                        if (tablero[1][val] != jugador) {
                            if (!esRecursivo) {
                                if (!util.siArrayContiene(amenazas, val)) {
                                    movimientosObligados.add(armarJugada(posicion, val, pieza));
                                    esObligatorio = true;
                                }
                            } else {
                                movimientosObligados.add(armarJugada(posicion, val, pieza));
                                esObligatorio = true;
                            }
                        }
                        b9 = false;
                    }
                } else {
                    b9 = false;
                }
            }
            factor++;
        } while ((a7 || b7 || a9 || b9) && factor < 8 && esRecursivo);

        return esObligatorio;
    }

    private boolean buscarMovimientosHorizontalVertical(int[][] tablero,
            int posicion, int jugador, boolean esRecursivo, int pieza, int[] amenazas, Movimientos esc,
            List<int[]> movimientos, List<int[]> movimientosObligados, boolean esObligatorio) {

        int factor = 1;
        int val;
        boolean a1 = true,
                b1 = true,
                a8 = true,
                b8 = true;
        do {
            if (a1) {
                val = posicion - (1 * factor);
                if (val >= 0 && val % 8 < 7 && (esc == null || esc.isHorizontalIzquierda())) {
                    if (tablero[1][val] == sincolor) {
                        if (!esObligatorio) {
                            if (!esRecursivo) {
                                if (!util.siArrayContiene(amenazas, val)) {
                                    movimientos.add(armarJugada(posicion, val, pieza));
                                }
                            } else {
                                movimientos.add(armarJugada(posicion, val, pieza));
                            }
                        }
                    } else {
                        if (tablero[1][val] != jugador) {
                            if (!esRecursivo) {
                                if (!util.siArrayContiene(amenazas, val)) {
                                    movimientosObligados.add(armarJugada(posicion, val, pieza));
                                    esObligatorio = true;
                                }
                            } else {
                                movimientosObligados.add(armarJugada(posicion, val, pieza));
                                esObligatorio = true;
                            }
                        }
                        a1 = false;
                    }
                } else {
                    a1 = false;
                }
            }
            if (b1) {
                val = posicion + (1 * factor);
                if (val % 8 > 0 && (esc == null || esc.isHorizontalDerecha())) {
                    if (tablero[1][val] == sincolor) {
                        if (!esObligatorio) {
                            if (!esRecursivo) {
                                if (!util.siArrayContiene(amenazas, val)) {
                                    movimientos.add(armarJugada(posicion, val, pieza));
                                }
                            } else {
                                movimientos.add(armarJugada(posicion, val, pieza));
                            }
                        }
                    } else {
                        if (tablero[1][val] != jugador) {
                            if (!esRecursivo) {
                                if (!util.siArrayContiene(amenazas, val)) {
                                    movimientosObligados.add(armarJugada(posicion, val, pieza));
                                    esObligatorio = true;
                                }
                            } else {
                                movimientosObligados.add(armarJugada(posicion, val, pieza));
                                esObligatorio = true;
                            }
                        }
                        b1 = false;
                    }
                } else {
                    b1 = false;
                }
            }
            if (a8) {
                val = posicion - (8 * factor);
                if (val >= 0 && (esc == null || esc.isVerticalInferior())) {
                    if (tablero[1][val] == sincolor) {
                        if (!esObligatorio) {
                            if (!esRecursivo) {
                                if (!util.siArrayContiene(amenazas, val)) {
                                    movimientos.add(armarJugada(posicion, val, pieza));
                                }
                            } else {
                                movimientos.add(armarJugada(posicion, val, pieza));
                            }
                        }
                    } else {
                        if (tablero[1][val] != jugador) {
                            if (!esRecursivo) {
                                if (!util.siArrayContiene(amenazas, val)) {
                                    movimientosObligados.add(armarJugada(posicion, val, pieza));
                                    esObligatorio = true;
                                }
                            } else {
                                movimientosObligados.add(armarJugada(posicion, val, pieza));
                                esObligatorio = true;
                            }
                        }
                        a8 = false;
                    }
                } else {
                    a8 = false;
                }
            }
            if (b8) {
                val = posicion + (8 * factor);
                if (val < 64 && (esc == null || esc.isVerticalSuperior())) {
                    if (tablero[1][val] == sincolor) {
                        if (!esObligatorio) {
                            if (!esRecursivo) {
                                if (!util.siArrayContiene(amenazas, val)) {
                                    movimientos.add(armarJugada(posicion, val, pieza));
                                }
                            } else {
                                movimientos.add(armarJugada(posicion, val, pieza));
                            }
                        }
                    } else {
                        if (tablero[1][val] != jugador) {
                            if (!esRecursivo) {
                                if (!util.siArrayContiene(amenazas, val)) {
                                    movimientosObligados.add(armarJugada(posicion, val, pieza));
                                    esObligatorio = true;
                                }
                            } else {
                                movimientosObligados.add(armarJugada(posicion, val, pieza));
                                esObligatorio = true;
                            }
                        }
                        b8 = false;
                    }
                } else {
                    b8 = false;
                }
            }
            factor++;
        } while ((a1 || b1 || a8 || b8) && factor < 8 && esRecursivo);

        return esObligatorio;
    }

    public int[] devolverCasillasAmenazadas(int[][] tablero, int jugador) {

        List<Integer> amenazas = new ArrayList<>();
        int ficha;
        int color;

        for (int i = 0; i < 64; i++) {
            color = tablero[1][i];
            if (color == jugador) {
                ficha = tablero[0][i];
                switch (ficha) {
                    case pawn:
                        switch (color) {
                            case white:
                                if (i % 8 != 0) {
                                    amenazas.add((tablero[0][i + 7] == king && tablero[1][i + 7] == black) ? 100 + i : i + 7);
                                }
                                if ((i + 1) % 8 != 0) {
                                    amenazas.add((tablero[0][i + 9] == king && tablero[1][i + 9] == black) ? 100 + i : i + 9);
                                }
                                break;
                            case black:
                                if ((i + 1) % 8 != 0) {
                                    amenazas.add((tablero[0][i - 7] == king && tablero[1][i - 7] == white) ? 100 + i : i - 7);
                                }
                                if (i % 8 != 0) {
                                    amenazas.add((tablero[0][i - 9] == king && tablero[1][i - 9] == white) ? 100 + i : i - 9);
                                }
                                break;
                        }
                        break;
                    case knight:
                        //+6 -6
                        if ((i < 56 && i % 8 > 1)) {
                            amenazas.add((tablero[0][i + 6] == king && tablero[1][i + 6] != jugador) ? 100 + i : i + 6);
                        }
                        if (i > 7 && i % 8 < 6) {
                            amenazas.add((tablero[0][i - 6] == king && tablero[1][i - 6] != jugador) ? 100 + i : i - 6);
                        }
                        //+10 -10
                        if (i < 56 && i % 8 < 6) {
                            amenazas.add((tablero[0][i + 10] == king && tablero[1][i + 10] != jugador) ? 100 + i : i + 10);
                        }
                        if (i > 7 && i % 8 > 1) {
                            amenazas.add((tablero[0][i - 10] == king && tablero[1][i - 10] != jugador) ? 100 + i : i - 10);
                        }
                        //+15 -15
                        if (i < 48 && i % 8 > 0) {
                            amenazas.add((tablero[0][i + 15] == king && tablero[1][i + 15] != jugador) ? 100 + i : i + 15);
                        }
                        if (i > 15 && i % 8 < 7) {
                            amenazas.add((tablero[0][i - 15] == king && tablero[1][i - 15] != jugador) ? 100 + i : i - 15);
                        }
                        //+17 -17
                        if (i < 48 && i % 8 < 7) {
                            amenazas.add((tablero[0][i + 17] == king && tablero[1][i + 17] != jugador) ? 100 + i : i + 17);
                        }
                        if ((i > 15 && i % 8 > 0)) {
                            amenazas.add((tablero[0][i - 17] == king && tablero[1][i - 17] != jugador) ? 100 + i : i - 17);
                        }
                        break;
                    case bishop:
                        this.buscarAmenazasDiagonal(tablero, i, jugador, true, amenazas);
                        break;
                    case rook:
                        this.buscarAmenazasHorizontalVertical(tablero, i, jugador, true, amenazas);
                        break;
                    case queen:
                        this.buscarAmenazasDiagonal(tablero, i, jugador, true, amenazas);
                        this.buscarAmenazasHorizontalVertical(tablero, i, jugador, true, amenazas);
                        break;
                    case king:
                        this.buscarAmenazasDiagonal(tablero, i, jugador, false, amenazas);
                        this.buscarAmenazasHorizontalVertical(tablero, i, jugador, false, amenazas);
                        break;
                }
            }
        }

        return util.convertirListtoArray(amenazas);
    }

    private void buscarAmenazasDiagonal(int[][] tablero, int pos, int jugador, boolean esRecursivo, List<Integer> amenazas) {

        int factor = 1;
        int val;
        boolean a7 = true,
                b7 = true,
                a9 = true,
                b9 = true;
        do {
            if (a7) {
                val = pos - (7 * factor);
                if (val % 8 > 0) {
                    if (tablero[1][val] != sincolor && !(tablero[0][val] == king && tablero[1][val] != jugador)) {
                        a7 = false;
                    }
                    if (tablero[0][val] == king && tablero[1][val] != jugador) {
                        amenazas.add(100 + pos);
                    } else {
                        amenazas.add(val);
                    }
                } else {
                    a7 = false;
                }
            }
            if (b7) {
                val = pos + (7 * factor);
                if (val < 64 && val % 8 < 7) {
                    if (tablero[1][val] != sincolor && !(tablero[0][val] == king && tablero[1][val] != jugador)) {
                        b7 = false;
                    }
                    if (tablero[0][val] == king && tablero[1][val] != jugador) {
                        amenazas.add(100 + pos);
                    } else {
                        amenazas.add(val);
                    }
                } else {
                    b7 = false;
                }
            }
            if (a9) {
                val = pos - (9 * factor);
                if (val >= 0 && val % 8 < 7) {
                    if (tablero[1][val] != sincolor && !(tablero[0][val] == king && tablero[1][val] != jugador)) {
                        a9 = false;
                    }
                    if (tablero[0][val] == king && tablero[1][val] != jugador) {
                        amenazas.add(100 + pos);
                    } else {
                        amenazas.add(val);
                    }
                } else {
                    a9 = false;
                }
            }
            if (b9) {
                val = pos + (9 * factor);
                if (val < 64 && val % 8 > 0) {
                    if (tablero[1][val] != sincolor && !(tablero[0][val] == king && tablero[1][val] != jugador)) {
                        b9 = false;
                    }
                    if (tablero[0][val] == king && tablero[1][val] != jugador) {
                        amenazas.add(100 + pos);
                    } else {
                        amenazas.add(val);
                    }
                } else {
                    b9 = false;
                }
            }
            factor++;
        } while ((a7 || b7 || a9 || b9) && factor < 8 && esRecursivo);
    }

    private void buscarAmenazasHorizontalVertical(int[][] tablero, int pos, int jugador, boolean esRecursivo, List<Integer> amenazas) {
        int factor = 1;
        int val;
        boolean a1 = true,
                b1 = true,
                a8 = true,
                b8 = true;
        do {
            if (a1) {
                val = pos - (1 * factor);
                if (val >= 0 && val % 8 < 7) {
                    if (tablero[1][val] != sincolor && !(tablero[0][val] == king && tablero[1][val] != jugador)) {
                        a1 = false;
                    }
                    if (tablero[0][val] == king && tablero[1][val] != jugador) {
                        amenazas.add(100 + pos);
                    } else {
                        amenazas.add(val);
                    }
                } else {
                    a1 = false;
                }
            }
            if (b1) {
                val = pos + (1 * factor);
                if (val % 8 > 0) {
                    if (tablero[1][val] != sincolor && !(tablero[0][val] == king && tablero[1][val] != jugador)) {
                        b1 = false;
                    }
                    if (tablero[0][val] == king && tablero[1][val] != jugador) {
                        amenazas.add(100 + pos);
                    } else {
                        amenazas.add(val);
                    }
                } else {
                    b1 = false;
                }
            }
            if (a8) {
                val = pos - (8 * factor);
                if (val >= 0) {
                    if (tablero[1][val] != sincolor && !(tablero[0][val] == king && tablero[1][val] != jugador)) {
                        a8 = false;
                    }
                    if (tablero[0][val] == king && tablero[1][val] != jugador) {
                        amenazas.add(100 + pos);
                    } else {
                        amenazas.add(val);
                    }
                } else {
                    a8 = false;
                }
            }
            if (b8) {
                val = pos + (8 * factor);
                if (val < 64) {
                    if (tablero[1][val] != sincolor && !(tablero[0][val] == king && tablero[1][val] != jugador)) {
                        b8 = false;
                    }
                    if (tablero[0][val] == king && tablero[1][val] != jugador) {
                        amenazas.add(100 + pos);
                    } else {
                        amenazas.add(val);
                    }
                } else {
                    b8 = false;
                }
            }
            factor++;
        } while ((a1 || b1 || a8 || b8) && factor < 8 && esRecursivo);
    }

    public void buscarJugadasenJaque(Jugadas jugadas, int[][] tablero, int[] amenazas, int jugador,
            int jug_ini, int jug_fin, Map<Integer, Movimientos> amenazasescondidas, int posicion_rey,
            int pos_jaque, int rival) {

        List<int[]> movimientos = new ArrayList<>();
        List<int[]> movimientosObligados = new ArrayList<>();
        List<int[]> defensas;
        boolean esObligatorio = false;

        //buscamos los movimientos del rey
        for (int i = 0; i < 64; i++) {
            int ficha = tablero[0][i];
            int color = tablero[1][i];

            if (ficha == king && color == jugador) {
                esObligatorio = this.buscarMovimientosHorizontalVertical(tablero, i, jugador, false, king, amenazas, null,
                        movimientos, movimientosObligados, esObligatorio);
                esObligatorio = this.buscarMovimientosDiagonal(tablero, i, jugador, false, king, amenazas, null,
                        movimientos, movimientosObligados, esObligatorio);
                break;
            }
        }

        if (pos_jaque == 100) {
            jugadas.setEsObligatorio(esObligatorio);
            jugadas.setJugadas(esObligatorio ? movimientosObligados : movimientos);
            jugadas.setHayJaque(!esObligatorio);
        } else {
            //buscar las jugadas que pueden cubrir el jaque o comer la pieza del jaque
            defensas = this.devolverCasillasDefensivas(tablero, jugador, jug_ini, jug_fin, amenazasescondidas);

            //buscamos defensas que maten el jaque
            for (int[] d : defensas) {
                int fin = d[2];

                if (fin > 99) {
                    if (jug_fin == pos_jaque) {
                        if (d.length > 3) {
                            movimientosObligados.add(this.armarJugadaConProm(d[1], fin - 100, d[0], d[3]));
                        } else {
                            movimientosObligados.add(this.armarJugada(d[1], fin - 100, d[0]));
                        }
                    }
                } else {
                    if (fin == pos_jaque) {
                        movimientosObligados.add(d);
                    }
                }
            }

            if (!movimientosObligados.isEmpty()) {
                jugadas.setJugadas(movimientosObligados);
                jugadas.setEsObligatorio(true);
            } else {
                jugadas.setJugadas(movimientos);
                jugadas.setEsObligatorio(false);
                jugadas.setHayJaque(true);

                if (tablero[0][pos_jaque] == bishop || tablero[0][pos_jaque] == rook || tablero[0][pos_jaque] == queen) {
                    //buscamos jugadas que obstruyan el jaque si la ficha que da jaque es bishop, rook o queen                
                    if (posicion_rey < pos_jaque) {
                        int diff = pos_jaque - posicion_rey;
                        if (diff < 7 || (diff == 7 && posicion_rey % 8 == 0)) {
                            for (int i = posicion_rey + 1; i < pos_jaque; i++) {
                                for (int[] d : defensas) {
                                    int fin = d[2];
                                    if (fin == i) {
                                        movimientos.add(d);
                                    }
                                }
                            }
                        } else if (diff % 7 == 0) {
                            for (int i = posicion_rey + 7; i < pos_jaque; i = i + 7) {
                                for (int[] d : defensas) {
                                    int fin = d[2];
                                    if (fin == i) {
                                        movimientos.add(d);
                                    }
                                }
                            }
                        } else if (diff % 8 == 0) {
                            for (int i = posicion_rey + 8; i < pos_jaque; i = i + 8) {
                                for (int[] d : defensas) {
                                    int fin = d[2];
                                    if (fin == i) {
                                        movimientos.add(d);
                                    }
                                }
                            }
                        } else if (diff % 9 == 0) {
                            for (int i = posicion_rey + 9; i < pos_jaque; i = i + 9) {
                                for (int[] d : defensas) {
                                    int fin = d[2];
                                    if (fin == i) {
                                        movimientos.add(d);
                                    }
                                }
                            }
                        }
                    } else { //  pos_jaque < posicion_rey
                        int diff = posicion_rey - pos_jaque;
                        if (diff < 7 || (diff == 7 && pos_jaque % 8 == 0)) {
                            for (int i = pos_jaque + 1; i < posicion_rey; i++) {
                                for (int[] d : defensas) {
                                    int fin = d[2];
                                    if (fin == i) {
                                        movimientos.add(d);
                                    }
                                }
                            }
                        } else if (diff % 7 == 0) {
                            for (int i = pos_jaque + 7; i < posicion_rey; i = i + 7) {
                                for (int[] d : defensas) {
                                    int fin = d[2];
                                    if (fin == i) {
                                        movimientos.add(d);
                                    }
                                }
                            }
                        } else if (diff % 8 == 0) {
                            for (int i = pos_jaque + 8; i < posicion_rey; i = i + 8) {
                                for (int[] d : defensas) {
                                    int fin = d[2];
                                    if (fin == i) {
                                        movimientos.add(d);
                                    }
                                }
                            }
                        } else if (diff % 9 == 0) {
                            for (int i = pos_jaque + 9; i < posicion_rey; i = i + 9) {
                                for (int[] d : defensas) {
                                    int fin = d[2];
                                    if (fin == i) {
                                        movimientos.add(d);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    private List<int[]> devolverCasillasDefensivas(int[][] tablero, int jugador,
            int jug_ini, int jug_fin, Map<Integer, Movimientos> amenazasescondidas) {

        List<int[]> defensas = new ArrayList<>();
        Movimientos esc = null;
        int ficha;
        int color;

        for (int i = 0; i < 64; i++) {
            color = tablero[1][i];

            if (color == jugador) {
                if (amenazasescondidas != null) {
                    esc = amenazasescondidas.get(i);

                    if (esc != null && esc.isSinMovimientos()) {
                        continue;
                    }
                }
                ficha = tablero[0][i];
                switch (ficha) {
                    case pawn:
                        switch (color) {
                            case white:
                                if (tablero[0][i + 8] == vacio && (esc == null || esc.isVerticalSuperior())) {
                                    if (i + 8 > 55 && i + 8 < 64) {
                                        defensas.add(armarJugadaConProm(i, i + 8, pawn, queen));
                                        defensas.add(armarJugadaConProm(i, i + 8, pawn, rook));
                                        defensas.add(armarJugadaConProm(i, i + 8, pawn, bishop));
                                        defensas.add(armarJugadaConProm(i, i + 8, pawn, knight));
                                    } else {
                                        defensas.add(armarJugada(i, i + 8, pawn));
                                        if ((i >= 8 && i <= 15) && tablero[0][i + 16] == vacio) {
                                            defensas.add(armarJugada(i, i + 16, pawn));
                                        }
                                    }
                                }
                                if (i % 8 != 0 && (esc == null || esc.isDiagonalSuperiorIzquierda())) {
                                    if (tablero[0][i + 7] != vacio) {
                                        if (tablero[1][i + 7] == black) {
                                            if (i + 7 > 55 && i + 7 < 64) {
                                                defensas.add(armarJugadaConProm(i, i + 7, pawn, queen));
                                                defensas.add(armarJugadaConProm(i, i + 7, pawn, rook));
                                                defensas.add(armarJugadaConProm(i, i + 7, pawn, bishop));
                                                defensas.add(armarJugadaConProm(i, i + 7, pawn, knight));
                                            } else {
                                                defensas.add(armarJugada(i, i + 7, pawn));
                                            }
                                        }
                                    } else {
                                        if (jug_ini != -1 && jug_fin != -1 && tablero[0][jug_fin] == pawn) {
                                            if (jug_ini >= 48 && jug_ini <= 55 && jug_fin == jug_ini - 16 && jug_fin == i - 1) {
                                                defensas.add(armarJugada(i, 100 + i + 7, pawn));
                                            }
                                        }
                                    }
                                }
                                if ((i + 1) % 8 != 0 && (esc == null || esc.isDiagonalSuperiorDerecha())) {
                                    if (tablero[0][i + 9] != vacio) {
                                        if (tablero[1][i + 9] == black) {
                                            if (i + 9 > 55 && i + 9 < 64) {
                                                defensas.add(armarJugadaConProm(i, i + 9, pawn, queen));
                                                defensas.add(armarJugadaConProm(i, i + 9, pawn, rook));
                                                defensas.add(armarJugadaConProm(i, i + 9, pawn, bishop));
                                                defensas.add(armarJugadaConProm(i, i + 9, pawn, knight));
                                            } else {
                                                defensas.add(armarJugada(i, i + 9, pawn));
                                            }
                                        }
                                    } else {
                                        if (jug_ini != -1 && jug_fin != -1 && tablero[0][jug_fin] == pawn) {
                                            if (jug_ini >= 48 && jug_ini <= 55 && jug_fin == jug_ini - 16 && jug_fin == i + 1) {
                                                defensas.add(armarJugada(i, 100 + i + 9, pawn));
                                            }
                                        }
                                    }
                                }
                                break;
                            case black:
                                if (tablero[0][i - 8] == vacio && (esc == null || esc.isVerticalInferior())) {
                                    if (i - 8 >= 0 && i - 8 < 8) {
                                        defensas.add(armarJugadaConProm(i, i - 8, pawn, queen));
                                        defensas.add(armarJugadaConProm(i, i - 8, pawn, rook));
                                        defensas.add(armarJugadaConProm(i, i - 8, pawn, bishop));
                                        defensas.add(armarJugadaConProm(i, i - 8, pawn, knight));
                                    } else {
                                        defensas.add(armarJugada(i, i - 8, pawn));
                                        if ((i >= 48 && i <= 55) && tablero[0][i - 16] == vacio) {
                                            defensas.add(armarJugada(i, i - 16, pawn));
                                        }
                                    }
                                }
                                if ((i + 1) % 8 != 0 && (esc == null || esc.isDiagonalInferiorDerecha())) {
                                    if (tablero[0][i - 7] != vacio) {
                                        if (tablero[1][i - 7] == white) {
                                            if (i - 7 > 0 && i - 7 < 8) {
                                                defensas.add(armarJugadaConProm(i, i - 7, pawn, queen));
                                                defensas.add(armarJugadaConProm(i, i - 7, pawn, rook));
                                                defensas.add(armarJugadaConProm(i, i - 7, pawn, bishop));
                                                defensas.add(armarJugadaConProm(i, i - 7, pawn, knight));
                                            } else {
                                                defensas.add(armarJugada(i, i - 7, pawn));
                                            }
                                        }
                                    } else {
                                        if (jug_ini != -1 && jug_fin != -1 && tablero[0][jug_fin] == pawn) {
                                            if (jug_ini >= 8 && jug_ini <= 15 && jug_fin == jug_ini + 16 && jug_fin == i + 1) {
                                                defensas.add(armarJugada(i, 100 + i - 7, pawn));
                                            }
                                        }
                                    }
                                }
                                if (i % 8 != 0 && (esc == null || esc.isDiagonalInferiorIzquierda())) {
                                    if (tablero[0][i - 9] != vacio) {
                                        if (tablero[1][i - 9] == white) {
                                            if (i - 9 >= 0 && i - 9 < 8) {
                                                defensas.add(armarJugadaConProm(i, i - 9, pawn, queen));
                                                defensas.add(armarJugadaConProm(i, i - 9, pawn, rook));
                                                defensas.add(armarJugadaConProm(i, i - 9, pawn, bishop));
                                                defensas.add(armarJugadaConProm(i, i - 9, pawn, knight));
                                            } else {
                                                defensas.add(armarJugada(i, i - 9, pawn));
                                            }
                                        }
                                    } else {
                                        if (jug_ini != -1 && jug_fin != -1 && tablero[0][jug_fin] == pawn) {
                                            if (jug_ini >= 8 && jug_ini <= 15 && jug_fin == jug_ini + 16 && jug_fin == i - 1) {
                                                defensas.add(armarJugada(i, 100 + i - 9, pawn));
                                            }
                                        }
                                    }
                                }
                                break;
                        }
                        break;
                    case knight:
                        //+6 -6
                        if (i < 56 && i % 8 > 1) {
                            if (tablero[1][i + 6] == sincolor) {
                                defensas.add(armarJugada(i, i + 6, knight));
                            } else if (tablero[1][i + 6] != jugador) {
                                defensas.add(armarJugada(i, i + 6, knight));
                            }
                        }
                        if (i > 7 && i % 8 < 6) {
                            if (tablero[1][i - 6] == sincolor) {
                                defensas.add(armarJugada(i, i - 6, knight));
                            } else if (tablero[1][i - 6] != jugador) {
                                defensas.add(armarJugada(i, i - 6, knight));
                            }
                        }
                        //+10 -10
                        if (i < 56 && i % 8 < 6) {
                            if (tablero[1][i + 10] == sincolor) {
                                defensas.add(armarJugada(i, i + 10, knight));
                            } else if (tablero[1][i + 10] != jugador) {
                                defensas.add(armarJugada(i, i + 10, knight));
                            }
                        }
                        if (i > 7 && i % 8 > 1) {
                            if (tablero[1][i - 10] == sincolor) {
                                defensas.add(armarJugada(i, i - 10, knight));
                            } else if (tablero[1][i - 10] != jugador) {
                                defensas.add(armarJugada(i, i - 10, knight));
                            }
                        }
                        //+15 -15
                        if (i < 48 && i % 8 > 0) {
                            if (tablero[1][i + 15] == sincolor) {
                                defensas.add(armarJugada(i, i + 15, knight));
                            } else if (tablero[1][i + 15] != jugador) {
                                defensas.add(armarJugada(i, i + 15, knight));
                            }
                        }
                        if (i > 15 && i % 8 < 7) {
                            if (tablero[1][i - 15] == sincolor) {
                                defensas.add(armarJugada(i, i - 15, knight));
                            } else if (tablero[1][i - 15] != jugador) {
                                defensas.add(armarJugada(i, i - 15, knight));
                            }
                        }
                        //+17 -17
                        if (i < 48 && i % 8 < 7) {
                            if (tablero[1][i + 17] == sincolor) {
                                defensas.add(armarJugada(i, i + 17, knight));
                            } else if (tablero[1][i + 17] != jugador) {
                                defensas.add(armarJugada(i, i + 17, knight));
                            }
                        }
                        if (i > 15 && i % 8 > 0) {
                            if (tablero[1][i - 17] == sincolor) {
                                defensas.add(armarJugada(i, i - 17, knight));
                            } else if (tablero[1][i - 17] != jugador) {
                                defensas.add(armarJugada(i, i - 17, knight));
                            }
                        }
                        break;
                    case bishop:
                        this.buscarDefensasDiagonal(tablero, i, jugador, bishop, esc, defensas);
                        break;
                    case rook:
                        this.buscarDefensasHorizontalVertical(tablero, i, jugador, rook, esc, defensas);
                        break;
                    case queen:
                        this.buscarDefensasDiagonal(tablero, i, jugador, queen, esc, defensas);
                        this.buscarDefensasHorizontalVertical(tablero, i, jugador, queen, esc, defensas);
                        break;
                }
            }
        }

        return defensas;
    }

    private void buscarDefensasDiagonal(int[][] tablero, int posicion, int jugador, int pieza, Movimientos esc,
            List<int[]> defensas) {

        int factor = 1;
        int val;
        boolean a7 = true,
                b7 = true,
                a9 = true,
                b9 = true;
        do {
            if (a7) {
                val = posicion - (7 * factor);
                if (val % 8 > 0 && (esc == null || esc.isDiagonalInferiorDerecha())) {
                    if (tablero[1][val] == sincolor) {
                        defensas.add(armarJugada(posicion, val, pieza));
                    } else {
                        if (tablero[1][val] != jugador) {
                            defensas.add(armarJugada(posicion, val, pieza));
                        }
                        a7 = false;
                    }
                } else {
                    a7 = false;
                }
            }
            if (b7) {
                val = posicion + (7 * factor);
                if (val < 64 && val % 8 < 7 && (esc == null || esc.isDiagonalSuperiorIzquierda())) {
                    if (tablero[1][val] == sincolor) {
                        defensas.add(armarJugada(posicion, val, pieza));
                    } else {
                        if (tablero[1][val] != jugador) {
                            defensas.add(armarJugada(posicion, val, pieza));
                        }
                        b7 = false;
                    }
                } else {
                    b7 = false;
                }
            }
            if (a9) {
                val = posicion - (9 * factor);
                if (val >= 0 && val % 8 < 7 && (esc == null || esc.isDiagonalInferiorIzquierda())) {
                    if (tablero[1][val] == sincolor) {
                        defensas.add(armarJugada(posicion, val, pieza));
                    } else {
                        if (tablero[1][val] != jugador) {
                            defensas.add(armarJugada(posicion, val, pieza));
                        }
                        a9 = false;
                    }
                } else {
                    a9 = false;
                }
            }
            if (b9) {
                val = posicion + (9 * factor);
                if (val < 64 && val % 8 > 0 && (esc == null || esc.isDiagonalSuperiorDerecha())) {
                    if (tablero[1][val] == sincolor) {
                        defensas.add(armarJugada(posicion, val, pieza));
                    } else {
                        if (tablero[1][val] != jugador) {
                            defensas.add(armarJugada(posicion, val, pieza));
                        }
                        b9 = false;
                    }
                } else {
                    b9 = false;
                }
            }
            factor++;
        } while ((a7 || b7 || a9 || b9) && factor < 8);

    }

    private void buscarDefensasHorizontalVertical(int[][] tablero, int posicion,
            int jugador, int pieza, Movimientos esc, List<int[]> defensas) {

        int factor = 1;
        int val;
        boolean a1 = true,
                b1 = true,
                a8 = true,
                b8 = true;
        do {
            if (a1) {
                val = posicion - (1 * factor);
                if (val >= 0 && val % 8 < 7 && (esc == null || esc.isHorizontalIzquierda())) {
                    if (tablero[1][val] == sincolor) {
                        defensas.add(armarJugada(posicion, val, pieza));
                    } else {
                        if (tablero[1][val] != jugador) {
                            defensas.add(armarJugada(posicion, val, pieza));
                        }
                        a1 = false;
                    }
                } else {
                    a1 = false;
                }
            }
            if (b1) {
                val = posicion + (1 * factor);
                if (val % 8 > 0 && (esc == null || esc.isHorizontalDerecha())) {
                    if (tablero[1][val] == sincolor) {
                        defensas.add(armarJugada(posicion, val, pieza));
                    } else {
                        if (tablero[1][val] != jugador) {
                            defensas.add(armarJugada(posicion, val, pieza));
                        }
                        b1 = false;
                    }
                } else {
                    b1 = false;
                }
            }
            if (a8) {
                val = posicion - (8 * factor);
                if (val >= 0 && (esc == null || esc.isVerticalInferior())) {
                    if (tablero[1][val] == sincolor) {
                        defensas.add(armarJugada(posicion, val, pieza));
                    } else {
                        if (tablero[1][val] != jugador) {
                            defensas.add(armarJugada(posicion, val, pieza));
                        }
                        a8 = false;
                    }
                } else {
                    a8 = false;
                }
            }
            if (b8) {
                val = posicion + (8 * factor);
                if (val < 64 && (esc == null || esc.isVerticalSuperior())) {
                    if (tablero[1][val] == sincolor) {
                        defensas.add(armarJugada(posicion, val, pieza));
                    } else {
                        if (tablero[1][val] != jugador) {
                            defensas.add(armarJugada(posicion, val, pieza));
                        }
                        b8 = false;
                    }
                } else {
                    b8 = false;
                }
            }
            factor++;
        } while ((a1 || b1 || a8 || b8) && factor < 8);

    }

    public Map<Integer, Movimientos> devolverCasillasAmenazadasEscondidas(int[][] tablero, int jugador, int rival, int jug_ini, int jug_fin, int pos_king) {
        //map< ini, [fin]>
        Map<Integer, Movimientos> escondidas = new HashMap<>();
        int ficha;
        int color;

        for (int i = 0; i < 64; i++) {
            color = tablero[1][i];

            if (color == jugador) {
                ficha = tablero[0][i];
                switch (ficha) {
                    case bishop:
                        if (util.estanEnDiagonal(i, pos_king) && Math.abs(i - pos_king) > 10) {
                            this.buscarAmenazasEscondidasDiagonal(tablero, rival, i, pos_king, escondidas);
                        }
                        break;
                    case rook:
                        if ((util.enFila(i, pos_king) && Math.abs(i - pos_king) > 1) || (util.enColumna(i, pos_king) && Math.abs(i - pos_king) > 15)) {
                            this.buscarAmenazasEscondidasHorizontalVertical(tablero, rival,
                                    i, pos_king, jug_ini, jug_fin, escondidas);
                        }
                        break;
                    case queen:
                        if (util.estanEnDiagonal(i, pos_king) && Math.abs(i - pos_king) > 10) {
                            this.buscarAmenazasEscondidasDiagonal(tablero, rival, i, pos_king, escondidas);
                        }
                        if ((util.enFila(i, pos_king) && Math.abs(i - pos_king) > 1) || (util.enColumna(i, pos_king) && Math.abs(i - pos_king) > 15)) {
                            this.buscarAmenazasEscondidasHorizontalVertical(tablero, rival,
                                    i, pos_king, jug_ini, jug_fin, escondidas);
                        }
                        break;
                }
            }
        }

        return escondidas;
    }

    private void buscarAmenazasEscondidasDiagonal(int[][] tablero,
            int jugador, int pos, int pos_king, Map<Integer, Movimientos> escondidas) {

        int factor = 1;
        int cont = 0;
        int temporal = -1;
        int val;
        Movimientos m;

        if (pos > pos_king) {
            if ((pos - pos_king) % 7 == 0 && pos - pos_king < 63) {
                val = pos - (7 * factor);
                do {
                    if (tablero[1][val] == jugador) {
                        cont++;
                        if (cont < 2) {
                            temporal = val;
                        } else {
                            temporal = -1;
                            break;
                        }
                    } else if (tablero[1][val] != sincolor) {
                        temporal = -1;
                        break;
                    }
                    factor++;
                } while ((val = pos - (7 * factor)) != pos_king);

                if (temporal != -1) {
                    switch (tablero[0][temporal]) {
                        case knight:
                        case rook:
                            escondidas.put(temporal, new Movimientos(true));
                            break;
                        case pawn:
                        case bishop:
                        case queen:
                            m = new Movimientos();
                            m.setDiagonalSuperiorIzquierda(true);
                            m.setDiagonalInferiorDerecha(true);
                            escondidas.put(temporal, m);
                            break;
                    }
                }
            } else { //i-9
                val = pos - (9 * factor);
                do {
                    if (tablero[1][val] == jugador) {
                        cont++;
                        if (cont < 2) {
                            temporal = val;
                        } else {
                            temporal = -1;
                            break;
                        }
                    } else if (tablero[1][val] != sincolor) {
                        temporal = -1;
                        break;
                    }
                    factor++;
                } while ((val = pos - (9 * factor)) != pos_king);

                if (temporal != -1) {
                    switch (tablero[0][temporal]) {
                        case knight:
                        case rook:
                            escondidas.put(temporal, new Movimientos(true));
                            break;
                        case pawn:
                        case bishop:
                        case queen:
                            m = new Movimientos();
                            m.setDiagonalSuperiorDerecha(true);
                            m.setDiagonalInferiorIzquierda(true);
                            escondidas.put(temporal, m);
                            break;
                    }
                }
            }
        } else { //pos_king > pos
            if ((pos_king - pos) % 7 == 0 && pos_king - pos < 63) {
                val = pos + (7 * factor);
                do {
                    if (tablero[1][val] == jugador) {
                        cont++;
                        if (cont < 2) {
                            temporal = val;
                        } else {
                            temporal = -1;
                            break;
                        }
                    } else if (tablero[1][val] != sincolor) {
                        temporal = -1;
                        break;
                    }
                    factor++;
                } while ((val = pos + (7 * factor)) != pos_king);

                if (temporal != -1) {
                    switch (tablero[0][temporal]) {
                        case knight:
                        case rook:
                            escondidas.put(temporal, new Movimientos(true));
                            break;
                        case pawn:
                        case bishop:
                        case queen:
                            m = new Movimientos();
                            m.setDiagonalSuperiorIzquierda(true);
                            m.setDiagonalInferiorDerecha(true);
                            escondidas.put(temporal, m);
                            break;
                    }
                }
            } else { //i+9
                val = pos + (9 * factor);
                do {
                    if (tablero[1][val] == jugador) {
                        cont++;
                        if (cont < 2) {
                            temporal = val;
                        } else {
                            temporal = -1;
                            break;
                        }
                    } else if (tablero[1][val] != sincolor) {
                        temporal = -1;
                        break;
                    }
                    factor++;
                } while ((val = pos + (9 * factor)) != pos_king);

                if (temporal != -1) {
                    switch (tablero[0][temporal]) {
                        case knight:
                        case rook:
                            escondidas.put(temporal, new Movimientos(true));
                            break;
                        case pawn:
                        case bishop:
                        case queen:
                            m = new Movimientos();
                            m.setDiagonalSuperiorDerecha(true);
                            m.setDiagonalInferiorIzquierda(true);
                            escondidas.put(temporal, m);
                            break;
                    }
                }
            }
        }
    }

    private void buscarAmenazasEscondidasHorizontalVertical(int[][] tablero,
            int jugador, int pos, int pos_king, int jug_ini, int jug_fin, Map<Integer, Movimientos> escondidas) {

        int factor = 1;
        int cont = 0;
        int temporal = -1;
        int opc = -1;
        int val;
        Movimientos m;

        if (pos > pos_king) {
            if (pos - pos_king > 1 && pos - pos_king < 8) {
                val = pos - factor;
                do {
                    if (tablero[1][val] == jugador) {
                        cont++;
                        if (cont < 2) {
                            temporal = val;
                            opc = 0;
                        } else {
                            temporal = -1;
                            break;
                        }
                    } else if (tablero[1][val] != sincolor) {
                        if (tablero[0][val] == pawn && val == jug_fin && Math.abs(jug_ini - jug_fin) == 16) {
                            if (cont == 1) {
                                if (tablero[0][val + 1] == pawn) {
                                    temporal = val + 1;
                                    opc = 1;
                                } else {
                                    temporal = -1;
                                    break;
                                }
                            } else {//cont = 0
                                if (tablero[0][val - 1] == pawn && tablero[1][val - 1] == jugador) {
                                    temporal = val - 1;
                                    opc = 2;
                                    cont++;
                                    factor++;
                                } else {
                                    break;
                                }
                            }
                        } else {
                            temporal = -1;
                            break;
                        }
                    }
                    factor++;
                } while ((val = pos - factor) != pos_king);
                //asignar valor
                if (temporal != -1) {
                    switch (opc) {
                        case 0:
                            switch (tablero[0][temporal]) {
                                case pawn:
                                case knight:
                                case bishop:
                                    escondidas.put(temporal, new Movimientos(true));
                                    break;
                                case rook:
                                case queen:
                                    m = new Movimientos();
                                    m.setHorizontalDerecha(true);
                                    m.setHorizontalIzquierda(true);
                                    escondidas.put(temporal, m);
                                    break;
                            }
                            break;
                        case 1:
                        case 2:
                            m = new Movimientos();
                            m.setVerticalInferior(true);
                            m.setVerticalSuperior(true);
                            escondidas.put(temporal, m);
                            break;
                    }
                }
            } else { //i-8
                val = pos - (8 * factor);
                do {
                    if (tablero[1][val] == jugador) {
                        cont++;
                        if (cont < 2) {
                            temporal = val;
                        } else {
                            temporal = -1;
                            break;
                        }
                    } else if (tablero[1][val] != sincolor) {
                        temporal = -1;
                        break;
                    }
                    factor++;
                } while ((val = pos - (8 * factor)) != pos_king);

                if (temporal != -1) {
                    switch (tablero[0][temporal]) {
                        case knight:
                        case bishop:
                            escondidas.put(temporal, new Movimientos(true));
                            break;
                        case pawn:
                        case rook:
                        case queen:
                            m = new Movimientos();
                            m.setVerticalInferior(true);
                            m.setVerticalSuperior(true);
                            escondidas.put(temporal, m);
                            break;
                    }
                }
            }
        } else { //pos_king > pos
            if (pos_king - pos > 1 && pos_king - pos < 8) {
                val = pos + factor;
                do {
                    if (tablero[1][val] == jugador) {
                        cont++;
                        if (cont < 2) {
                            temporal = val;
                            opc = 0;
                        } else {
                            temporal = -1;
                            break;
                        }
                    } else if (tablero[1][val] != sincolor) {
                        if (tablero[0][val] == pawn && val == jug_fin && Math.abs(jug_ini - jug_fin) == 16) {
                            if (cont == 1) {
                                if (tablero[0][val - 1] == pawn) {
                                    temporal = val - 1;
                                    opc = 1;
                                } else {
                                    temporal = -1;
                                    break;
                                }
                            } else {//cont = 0
                                if (tablero[0][val + 1] == pawn && tablero[1][val + 1] == jugador) {
                                    temporal = val + 1;
                                    opc = 2;
                                    cont++;
                                    factor++;
                                } else {
                                    break;
                                }
                            }
                        } else {
                            temporal = -1;
                            break;
                        }
                    }
                    factor++;
                } while ((val = pos + factor) != pos_king);
                //asignar valor
                if (temporal != -1) {
                    switch (opc) {
                        case 0:
                            switch (tablero[0][temporal]) {
                                case pawn:
                                case knight:
                                case bishop:
                                    escondidas.put(temporal, new Movimientos(true));
                                    break;
                                case rook:
                                case queen:
                                    m = new Movimientos();
                                    m.setHorizontalDerecha(true);
                                    m.setHorizontalIzquierda(true);
                                    escondidas.put(temporal, m);
                                    break;
                            }
                            break;
                        case 1:
                        case 2:
                            m = new Movimientos();
                            m.setVerticalInferior(true);
                            m.setVerticalSuperior(true);
                            escondidas.put(temporal, m);
                            break;
                    }
                }
            } else { //i+8
                val = pos + (8 * factor);
                do {
                    if (tablero[1][val] == jugador) {
                        cont++;
                        if (cont < 2) {
                            temporal = val;
                        } else {
                            temporal = -1;
                            break;
                        }
                    } else if (tablero[1][val] != sincolor) {
                        temporal = -1;
                        break;
                    }
                    factor++;
                } while ((val = pos + (8 * factor)) != pos_king);

                if (temporal != -1) {
                    switch (tablero[0][temporal]) {
                        case knight:
                        case bishop:
                            escondidas.put(temporal, new Movimientos(true));
                            break;
                        case pawn:
                        case rook:
                        case queen:
                            m = new Movimientos();
                            m.setVerticalInferior(true);
                            m.setVerticalSuperior(true);
                            escondidas.put(temporal, m);
                            break;
                    }
                }
            }
        }
    }

    private int[] armarJugada(int ini, int fin, int ficha) {
        return new int[]{ficha, ini, fin};
    }

    private int[] armarJugadaConProm(int ini, int fin, int ficha, int prom) {
        return new int[]{ficha, ini, fin, prom};
    }
}
